package com.baide.sanguanheyi.ct;

import org.dom4j.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat;
import java.util.*;

/**
 * xml解析及生成类
 */
@Component
public class XmlUtils {

    @Autowired
    CtConfigClass ctConfigClass;
    private static SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd");
    private static SimpleDateFormat sd2 = new SimpleDateFormat("HH:mm:ss");

    public String getContent(String message, Map<String, Object> map) {
        String xml = getXml(message, map);
        String head = ctConfigClass.getHead();
        head += xml.length() + "\r\n\r\n";
        return head + xml;
    }

    Map<String, Object> heartMap = new HashMap<>();

    /**
     * 获取心跳报文
     *
     * @return
     */
    public String getHeartContent() {
        if (heartMap.size() == 0) {
            heartMap.put("Source", "SS");
            heartMap.put("Target", "CT");
        }
        return getContent("ctHeartBeatRequest", heartMap);
    }

    /**
     * 发送条码数据给ct设备
     *
     * @param barcode
     * @return
     */
    public String getBarcodeMessage(String barcode) {
        Map<String, Object> barMap = new HashMap<>();
        barMap.put("Barcode", barcode);
        barMap.put("BillNo", barcode);
        barMap.put("RealBarcode", barcode);
        return getContent("ctBarcodeMessage", barMap);
    }

    /**
     * 生成xml
     *
     * @param message
     * @param map
     * @return
     */
    private String getXml(String message, Map<String, Object> map) {
        Document doc = DocumentHelper.createDocument();
        Element envelope = doc.addElement("Envelope");
        Element header = envelope.addElement("Header");
        Element body = envelope.addElement("Body");
        Element messageName = header.addElement("MessageName");
        messageName.addText(message);
        Element messageTime = header.addElement("MessageTime");
        Date date = new Date();
        messageTime.addText(sd.format(date) + "T" + sd2.format(date) + "+08:00");
        for (String key : map.keySet()) {
            Element element = body.addElement(key);
            element.addText(map.get(key).toString());
        }
        return doc.asXML();
    }

    public Map<String, Object> getString(String xml) {
        String substring = xml.substring(xml.indexOf("<Envelope>"));
        Map<String, Object> map = new HashMap<>();
        try {
            Document document = DocumentHelper.parseText(substring);
            Element rootElement = document.getRootElement();
            for (Iterator iterator = rootElement.elementIterator(); iterator.hasNext(); ) {
                Element e = (Element) iterator.next();
                List list = e.elements();
                if (list.size() > 0) {
                    map.put(e.getName(), Dom2Map(e));
                } else {
                    map.put(e.getName(), e.getText());
                }
            }
        } catch (DocumentException e) {
            e.printStackTrace();
        }
        return map;
    }

    public Map Dom2Map(Element e) {
        Map map = new HashMap();
        List list = e.elements();
        if (list.size() > 0) {
            for (int i = 0; i < list.size(); i++) {
                Element iter = (Element) list.get(i);
                List mapList = new ArrayList();
                if (iter.elements().size() > 0) {
                    Map m = Dom2Map(iter);
                    if (map.get(iter.getName()) != null) {
                        Object obj = map.get(iter.getName());
                        if (!obj.getClass().getName().equals("java.util.ArrayList")) {
                            mapList = new ArrayList();
                            mapList.add(obj);
                            mapList.add(m);
                        }
                        if (obj.getClass().getName().equals("java.util.ArrayList")) {
                            mapList = (List) obj;
                            mapList.add(m);
                        }
                        map.put(iter.getName(), mapList);
                    } else map.put(iter.getName(), m);
                } else {
                    if (map.get(iter.getName()) != null) {
                        Object obj = map.get(iter.getName());
                        if (!obj.getClass().getName().equals("java.util.ArrayList")) {
                            mapList = new ArrayList();
                            mapList.add(obj);
                            mapList.add(iter.getText());
                        }
                        if (obj.getClass().getName().equals("java.util.ArrayList")) {
                            mapList = (List) obj;
                            mapList.add(iter.getText());
                        }
                        map.put(iter.getName(), mapList);
                    } else map.put(iter.getName(), iter.getText());
                }
            }
        } else map.put(e.getName(), e.getText());
        return map;
    }
}
